#ifndef __ISERVICE_LOCATOR_IMPL_H__
#define __ISERVICE_LOCATOR_IMPL_H__

#include "iservice_locator.h"
#include "ibase_impl.h"

#include <string>
#include <map>


namespace Boss
{

  class IServiceLocatorImpl
    : public CoClassBase
        <
          TL::TypeListAdapter
            <
              IServiceLocator
            >
        >
  {
  public:
    BOSS_DECLARE_CLSID(835451e8-0c83-4439-9811-0563090c7cfd)

    // IServiceLocator
    virtual TResult BOSS_CALL_TYPE GetService(TGuid serviceId, IBase **service) const
    {
      if (!serviceId || !*serviceId || !service)
        return rcBadParam;
      ISyncObject Lock(GetSynObj());
      ServicePool::iterator Iter = Services.find(serviceId);
      if (Iter == Services.end())
        return rcFail;
      return Iter->second.QueryInterface(service);
    }
    virtual TResult BOSS_CALL_TYPE AddService(TGuid serviceId, IBase *service)
    {
      if (!serviceId || !*serviceId || !service)
        return rcBadParam;
      ISyncObject Lock(GetSynObj());
      if (Services.find(serviceId) != Services.end())
        return rcFail;
      Services[serviceId] = service;
      return rcOk;
    }
    virtual TResult BOSS_CALL_TYPE DelService(TGuid serviceId)
    {
      if (!serviceId || !*serviceId)
        return rcBadParam;
      ISyncObject Lock(GetSynObj());
      ServicePool::iterator Iter = Services.find(serviceId);
      if (Iter == Services.end())
        return rcFail;
      Services.erase(Iter);
      return rcOk;
    }

  private:
    typedef RefObjPtr<IBase> IBasePtr;
    typedef std::map<std::string, IBasePtr> ServicePool;
    mutable ServicePool Services;
  };

}

#endif  // !__ISERVICE_LOCATOR_IMPL_H__
